<template>
  <view class="container">
    <!-- 1. 天气预报模块 -->
    <view class="weather-container">
      <view class="weather-header">
        <text class="weather-title">{{ weatherData.city }}天气预报</text>
      </view>
      <view class="weather-content" v-if="weatherData.temperature">
        <view class="weather-item">温度：{{ weatherData.temperature }}℃</view>
        <view class="weather-item">天气：{{ weatherData.weather }}</view>
        <view class="weather-item">湿度：{{ weatherData.humidity }}</view>
        <view class="weather-item">空气质量：{{ weatherData.quality }}</view>
      </view>
      <view class="weather-loading" v-else-if="isLoading">
        <text>加载中...</text>
      </view>
      <view class="weather-error" v-else>
        <text>获取天气失败</text>
      </view>
    </view>

    <!-- 2. 搜索框（纯静态属性名） -->
    <view class="search-box">
      <uni-icons type="search" size="24" color="#999"></uni-icons>
      <input 
        type="text" 
        placeholder="搜索关键词" 
        v-model="searchKey" 
        @input="onSearch" 
      />
    </view>

    <!-- 3. 分类导航（纯静态属性名） -->
    <tab-banner 
      :list="categories" 
      :current="activeIndex" 
      @onTabClick="tabClick"
    ></tab-banner>

    <!-- 4. 数据更新提醒 -->
    <view class="update-tips" v-if="showUpdateTips">
      <text>{{ updateCount }}条内容更新</text>
    </view>

    <!-- 5. 新闻列表（滚动容器） -->
    <scroll-view 
      class="news-list" 
      scroll-y
      @scrolltolower="loadMore" 
      @refresherrefresh="onRefresh"
      refresher-enabled
      refresher-threshold="100"
      :refresher-triggered="isRefreshing"
    >
      <!-- 置顶新闻（参与过滤+静态属性名） -->
      <view v-for="item in topNewsList" :key="'top-' + item.id">
        <cardViewText
          :newsId="item.id"
          :title="item.title"
          :author="item.author"
          :comments="item.comments"
          :time="item.timedata"
          :isTop="item.isTop"
          :image="cleanedImage(item.imageList)"
          :mode="'news'"
          :bgColor="'#fff'"
          @click="goToDetail(item.id)"
        ></cardViewText>
      </view>

      <!-- 普通新闻 + 稳定广告（纯静态属性名） -->
      <view v-for="(item, index) in filteredNews" :key="item.id">
        <cardViewText
          :newsId="item.id"
          :title="item.title"
          :author="item.author"
          :comments="item.comments"
          :time="item.timedata"
          :isTop="item.isTop"
          :image="cleanedImage(item.imageList)"
          :mode="'news'"
          :bgColor="'#fff'"
          @click="goToDetail(item.id)"
        ></cardViewText>

        <!-- 广告：15秒切换+图文同步+清洗后数据 -->
        <cardViewText
          v-if="shouldShowAd(index)"
          :key="`ad-${index}-${currentAdIndex}`"
          :newsId="currentAd.id || `ad-${index}`"
          :title="currentAd.title"
          :author="currentAd.author"
          :comments="0"
          :time="''"
          :isTop="false"
          :images="cleanedAdImages(currentAd.images)"
          :mode="'ad'"
          :bgColor="currentAd.bgColor || '#fff'"
        ></cardViewText>
      </view>

      <!-- 加载提示 -->
      <view class="load-more-tips" v-if="isLoadingMore">加载中...</view>
      <view class="no-more-tips" v-else-if="noMoreData">没有更多数据了</view>
    </scroll-view>
  </view>
</template>

<script>
// 导入组件（路径请适配你的项目）
import cardViewText from '../../../../components/news.vue'
import tabBanner from '../../../../components/tabBanner.vue'
// 导入原始JSON并全局清洗
import rawNewsJson from '../../../../data/news.json'

// 全局递归清洗函数：彻底移除所有<!--/-->，包括属性名/值
const cleanData = (data) => {
  if (typeof data === 'string') {
    return data.replace(/<!--/g, '').replace(/-->/g, '').trim();
  }
  if (Array.isArray(data)) {
    return data.map(item => cleanData(item)).filter(item => item !== '');
  }
  if (typeof data === 'object' && data !== null) {
    const cleanedObj = {};
    for (const rawKey in data) {
      const cleanKey = rawKey.replace(/<!--/g, '').replace(/-->/g, '').trim();
      const cleanValue = cleanData(data[rawKey]);
      if (cleanValue !== undefined && cleanValue !== null && cleanValue !== '') {
        cleanedObj[cleanKey] = cleanValue;
      }
    }
    return cleanedObj;
  }
  return data;
};

// 清洗后的最终数据
const newsJson = cleanData(rawNewsJson)

export default {
  components: { 
    cardViewText,
    tabBanner 
  },
  data() {
    return {
      categories: newsJson.categories || [],
      newsList: newsJson.newsList || [],
      adList: newsJson.adList || [],
      weatherData: {},
      isLoading: false,
      weatherURL: "http://t.weather.sojson.com/api/weather/city/101230501",
      searchKey: "",
      activeIndex: 0,
      filteredNews: [],
      showUpdateTips: false,
      updateCount: 0,
      page: 1,
      pageSize: 5,
      isLoadingMore: false,
      noMoreData: false,
      isRefreshing: false,
      adPositions: new Set(),
      lastAdIndex: -1,
      currentAdIndex: 0,
      adTimer: null,
      adSwitchInterval: 15000,
    };
  },
  computed: {
    topNewsList() {
      const topList = this.newsList.filter(item => item.isTop);
      return this.filterByCondition(topList);
    },
    regularNewsList() {
      return this.newsList.filter(item => !item.isTop);
    },
    currentAd() {
      return this.adList[this.currentAdIndex] || {};
    }
  },
  onLoad() {
    this.getWeather();
    this.initNewsList();
    this.setupAutoRefresh();
    this.initAdTimer();
  },
  onUnload() {
    if (this.adTimer) {
      clearInterval(this.adTimer);
      this.adTimer = null;
    }
  },
  methods: {
    // 清洗单张新闻图片（强化版）
    cleanedImage(imageList) {
      if (!Array.isArray(imageList) || imageList.length === 0) return '';
      let imgUrl = imageList[0] || '';
      // 彻底移除注释符
      imgUrl = imgUrl.replace(/<!--/g, '').replace(/-->/g, '').trim();
      // 过滤DOM非法字符
      imgUrl = imgUrl.replace(/[<>\"'&`]/gi, '');
      // 校验URL有效性
      const validUrl = /^\/|^http(s)?:\/\//;
      return validUrl.test(imgUrl) ? imgUrl : '';
    },
    // 清洗广告图片数组（强化版）
    cleanedAdImages(images) {
      if (!Array.isArray(images) || images.length === 0) return [];
      return images.map(img => {
        img = img.replace(/<!--/g, '').replace(/-->/g, '').trim();
        img = img.replace(/[<>\"'&`]/gi, '');
        const validUrl = /^\/|^http(s)?:\/\//;
        return validUrl.test(img) ? img : '';
      }).filter(Boolean);
    },

    // 广告定时器
    initAdTimer() {
      if (this.adTimer) clearInterval(this.adTimer);
      this.adTimer = setInterval(() => {
        this.switchToNextAd();
        this.$forceUpdate();
      }, this.adSwitchInterval);
    },
    switchToNextAd() {
      if (this.adList.length <= 1) return;
      this.currentAdIndex = (this.currentAdIndex + 1) % this.adList.length;
    },

    // 新闻过滤逻辑
    filterByCondition(newsList) {
      let list = [...newsList];
      if (this.searchKey.trim()) {
        const keyword = this.searchKey.toLowerCase();
        list = list.filter(item => 
          item.title.toLowerCase().includes(keyword) || 
          item.author.toLowerCase().includes(keyword) ||
          (item.tags && item.tags.some(tag => tag.toLowerCase().includes(keyword)))
        );
      }
      if (this.activeIndex > 0) {
        const category = this.categories[this.activeIndex];
        list = list.filter(item => 
          item.tags && item.tags.includes(category)
        );
      }
      return list;
    },

    // 初始化新闻列表
    initNewsList() {
      this.filterNews();
      this.generateAdPositions();
    },
    // 获取天气预报
    getWeather() {
      this.isLoading = true;
      uni.request({
        url: this.weatherURL,
        method: "GET",
        timeout: 10000,
        success: (res) => {
          this.isLoading = false;
          if (res.data && res.data.status === 200 && res.data.data) {
            const data = res.data.data;
            this.weatherData = {
              city: res.data.cityInfo.city,
              temperature: data.wendu,
              weather: data.forecast[0].type,
              humidity: data.shidu,
              quality: data.quality,
              pm25: data.pm25
            };
          } else {
            this.useDefaultWeather();
          }
        },
        fail: (err) => {
          this.isLoading = false;
          this.useDefaultWeather();
          console.error("获取天气失败：", err);
        }
      });
    },
    // 天气默认值
    useDefaultWeather() {
      this.weatherData = {
        city: newsJson.config?.weatherCity || '默认城市',
        temperature: "23",
        weather: "多云",
        humidity: "65%",
        quality: "优",
        pm25: 22
      };
    },
    // 跳转新闻详情
    goToDetail(newsId) {
     uni.navigateTo({
       url: `/pages/news-detail/news-detail?id=${newsId}`
     })
   },
    // 分类切换
    tabClick(index) {
      this.activeIndex = index;
      this.page = 1;
      this.noMoreData = false;
      this.filterNews();
    },
    // 搜索功能
    onSearch() {
      this.page = 1;
      this.noMoreData = false;
      this.filterNews();
    },
    // 过滤普通新闻
    filterNews() {
      this.filteredNews = this.filterByCondition(this.regularNewsList).slice(0, this.page * this.pageSize);
      this.generateAdPositions();
    },
    // 生成广告位置
    generateAdPositions() {
      this.adPositions.clear();
      const totalItems = this.filteredNews.length;
      const adCount = Math.floor(totalItems / 3);
      
      for (let i = 0; i < adCount; i++) {
        let position;
        do {
          position = i * 3 + Math.floor(Math.random() * 2) + 1;
        } while (this.adPositions.has(position) || position >= totalItems);
        
        if (position < totalItems) {
          this.adPositions.add(position);
        }
      }
    },
    // 检查广告显示位置
    shouldShowAd(index) {
      return this.adPositions.has(index + 1);
    },
    // 下拉刷新
    onRefresh() {
      this.isRefreshing = true;
      
      setTimeout(() => {
        const newNews = [
          {
            id: Date.now() + 1,
            title: "实时更新：" + new Date().toLocaleTimeString() + "最新动态",
            author: "实时新闻",
            comments: Math.floor(Math.random() * 100),
            timedata: "刚刚",
            isTop: false,
            imageList: ["/static/images/news-default.jpg"],
            tags: ["实时", "热点"]
          }
        ];
        
        this.updateCount = newNews.length;
        this.showUpdateTips = true;
        
        this.newsList = [...newNews, ...this.newsList];
        this.filterNews();
        this.generateAdPositions();
        this.initAdTimer();

        setTimeout(() => {
          this.showUpdateTips = false;
        }, 3000);

        this.isRefreshing = false;
        uni.stopPullDownRefresh();
      }, 1000);
    },
    // 加载更多
    loadMore() {
      if (this.isLoadingMore || this.noMoreData) return;
      
      this.isLoadingMore = true;
      this.page++;

      setTimeout(() => {
        const filteredRegular = this.filterByCondition(this.regularNewsList);
        const totalItems = filteredRegular.length;
        const currentItems = this.page * this.pageSize;
        
        if (currentItems >= totalItems) {
          this.noMoreData = true;
        }
        
        this.filteredNews = filteredRegular.slice(0, currentItems);
        this.isLoadingMore = false;
        this.initAdTimer();
      }, 800);
    },
    // 自动刷新
    setupAutoRefresh() {
      setInterval(() => {
        this.getWeather();
      }, 5 * 60 * 1000);
      
      setInterval(() => {
        this.onRefresh();
      }, 10 * 60 * 1000);
    }
  }
};
</script>

<style scoped>
.container {
  background-color: #f5f5f5;
  min-height: 100vh;
  padding: 15rpx;
}

.weather-container {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 10px;
  padding: 20rpx;
  margin-bottom: 15rpx;
  color: white;
}
.weather-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10rpx;
}
.weather-title {
  font-size: 30rpx;
  font-weight: bold;
}
.weather-content {
  display: flex;
  flex-wrap: wrap;
  gap: 20rpx;
  padding: 10rpx 0;
}
.weather-item {
  font-size: 26rpx;
  opacity: 0.9;
}
.weather-loading, .weather-error {
  text-align: center;
  font-size: 26rpx;
  opacity: 0.9;
  padding: 10rpx 0;
}

.search-box {
  margin: 0 0 15rpx 0;
  padding: 15rpx 20rpx;
  background-color: #fff;
  border-radius: 30rpx;
  display: flex;
  align-items: center;
  box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);
}
.search-box input {
  margin-left: 10rpx;
  flex: 1;
  font-size: 28rpx;
  outline: none;
}

.update-tips {
  padding: 15rpx;
  text-align: center;
  font-size: 26rpx;
  color: #007AFF;
  background-color: #e6f7ff;
  border-radius: 10rpx;
  margin-bottom: 15rpx;
  border: 1rpx solid #91d5ff;
}

.news-list {
  height: calc(100vh - 300rpx);
  display: flex;
  flex-direction: column;
  gap: 15rpx;
}

.load-more-tips, .no-more-tips {
  text-align: center;
  font-size: 26rpx;
  color: #999;
  padding: 30rpx 0;
}
</style>